fix: track indexing issuance through the IssuanceAllocator (GIP-0089) - #334
Open
PaulieB14 wants to merge 2 commits into
Open
fix: track indexing issuance through the IssuanceAllocator (GIP-0089)#334PaulieB14 wants to merge 2 commits into
PaulieB14 wants to merge 2 commits into
Conversation
`GraphNetwork.networkGRTIssuancePerBlock` has read 120.73 GRT/block on Arbitrum
since GIP-0089 activated on 2026-09-01, when the rate the RewardsManager
actually issues at became 96.584. Every consumer computing indexing-reward APR
from this field — the schema documents it for exactly that — currently
overstates by 120.73/96.584 = 1.25x.
Two independent causes, either sufficient on its own:
1. WRONG GETTER. rewardsManager.ts read `issuancePerBlock()`. Once the
IssuanceAllocator was wired up (GIP-0076/GIP-0088) the RewardsManager mints
only its own allocation, and that legacy storage slot stopped being the rate
it issues at. On Arbitrum One today the slot still returns 120.73e18 while
`getAllocatedIssuancePerBlock()` returns 96.584e18. The getter was also
absent from abis/RewardsManagerStitched.json, so the mapping could not have
called it.
2. NO TRIGGER. The value is only refreshed by the RewardsManager's
`ParameterUpdated('issuancePerBlock')`. GIP-0089 changed the split on the
ALLOCATOR, so no such event was emitted and the field was never re-read.
Reproducible — the same block-scoped query either side of the change:
{
before: graphNetwork(id:"1", block:{number:500600000}) { networkGRTIssuancePerBlock }
after: graphNetwork(id:"1", block:{number:501148942}) { networkGRTIssuancePerBlock }
}
Both return 120730000000000000000. GIP-0089 took effect at Arbitrum block
500,701,945, between them.
On chain at the same moment:
RewardsManager 0x971B9d3d0Ae3ECa029CAB5eA1fB0F72c85e6a525
getAllocatedIssuancePerBlock() 0xe208d721 -> 96.584e18
issuancePerBlock() 0x6c080f18 -> 120.730e18
IssuanceAllocator 0xb64f29b2d81140ffc3a135e319561a1bd03b1a7e
getTargetAllocation(RewardsManager).selfMintingRate -> 96.584e18
CHANGES
- New IssuanceAllocator data source handling
`TargetAllocationUpdated(address,uint256,uint256)`. When the target is the
RewardsManager, `newSelfMintingRate` is the rate it will issue at, so the
event carries the value and no contract call is needed. This is the only
place a future re-split is observable: GIP-0088 Phase 3 moves a further
6 GRT/block to the Recurring Agreement Manager, taking the RewardsManager to
90.584, and would otherwise go unnoticed in the same way.
- rewardsManager.ts prefers `getAllocatedIssuancePerBlock()`, via try_ so it
still works on deployments predating the upgrade where the getter is absent.
- abis/RewardsManagerStitched.json gains the two getters it was missing.
- The allocator address is resolved from @graphprotocol/address-book, which
required bumping 1.1.0 -> ^1.3.0: 1.1.0 neither ships issuance/addresses.json
nor exports the path, while 1.3.0 exports "./*/addresses.json". It is
deployed on Arbitrum One and Arbitrum Sepolia only, and resolves empty
elsewhere, matching how subgraphService is handled.
VERIFIED
`yarn prepare:arbitrum` and `yarn prepare:arbitrum-sepolia` both resolve the
allocator (0xb64f29b2… and 0x76a0d756… respectively) and `yarn build` compiles.
The CI test-prep step (testAddressesL1/L2 + mustache) still produces a valid
config/addresses.ts on both layers.
Note for reviewers: picking up the 2026-09-01 allocation requires reindexing
from a start block at or before it, since the handler is event-driven. Whether
that warrants a resync of the deployed subgraphs is a maintainer call.
CI caught this: `Path: dataSources > 9 > source > address / Contract address is invalid` on both L1 and L2 test prep. I had used an empty string as the placeholder on networks without an allocator, but graph-cli requires 40 hex characters and every other absent contract in these fixtures — subgraphService, graphPayments, paymentsEscrow, graphTallyCollector — uses the zero address. Verified by running the exact CI steps rather than assuming: testAddressesL1 and testAddressesL2 both now complete mustache + codegen, and the matchstick suite passes 88/88.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
GraphNetwork.networkGRTIssuancePerBlockhas reported 120.73 GRT/block on Arbitrum since GIP-0089 activated on 2026-09-01, when the rate the RewardsManager actually issues at became 96.584. The schema documents this field for reward-rate maths ("To get annual rate do (networkGRTIssuancePerBlock * blocksPerYear)"), so every consumer computing indexing-reward APR from it currently overstates by120.73 / 96.584= exactly 1.25x.Reproducible
Same block-scoped query either side of the change (GIP-0089 took effect at Arbitrum block 500,701,945, between them):
{ before: graphNetwork(id: "1", block: { number: 500600000 }) { networkGRTIssuancePerBlock } after: graphNetwork(id: "1", block: { number: 501148942 }) { networkGRTIssuancePerBlock } }Both return
120730000000000000000. A fifth of issuance was redirected in between and the field is byte-identical.On chain at the same moment:
0x971B9d3d…a525getAllocatedIssuancePerBlock()0xe208d7210x971B9d3d…a525issuancePerBlock()0x6c080f180xb64f29b2…1a7egetTargetAllocation(RewardsManager).selfMintingRateCause
Two independent causes, either sufficient on its own:
Wrong getter.
rewardsManager.tsreadissuancePerBlock(). Once the IssuanceAllocator was wired up (GIP-0076 / GIP-0088) the RewardsManager mints only its own allocation, and that legacy storage slot stopped being the rate it issues at.getAllocatedIssuancePerBlock()was also absent fromabis/RewardsManagerStitched.json, so the mapping could not have called it.No trigger. The value is only refreshed by the RewardsManager's
ParameterUpdated('issuancePerBlock'). GIP-0089 changed the split on the allocator, so no such event fired and the field was never re-read.Changes
TargetAllocationUpdated(address,uint256,uint256). When the target is the RewardsManager,newSelfMintingRateis the rate it will issue at — the event carries the value, so no contract call is needed. This is the only place a future re-split is observable: GIP-0088 Phase 3 moves a further 6 GRT/block to the Recurring Agreement Manager, taking the RewardsManager to 90.584, and would otherwise go unnoticed the same way.rewardsManager.tsprefersgetAllocatedIssuancePerBlock(), viatry_so it still works on deployments predating the upgrade where the getter is absent.abis/RewardsManagerStitched.jsongains the two getters it was missing.@graphprotocol/address-book, which required bumping1.1.0 -> ^1.3.0: 1.1.0 neither shipsissuance/addresses.jsonnor exports the path, while 1.3.0 exports"./*/addresses.json". It is deployed on Arbitrum One and Arbitrum Sepolia only and resolves empty elsewhere, matching howsubgraphServiceis handled.Verification
yarn prepare:arbitrumandyarn prepare:arbitrum-sepoliaboth resolve the allocator (0xb64f29b2…/0x76a0d756…)yarn buildcompilestestAddressesL1/L2+ mustache) still produces a validconfig/addresses.tson both layersNote for reviewers
Picking up the 2026-09-01 allocation requires reindexing from a start block at or before it, since the handler is event-driven. Whether that warrants a resync of the deployed subgraphs is a maintainer call.
I targeted
mastersince that is where recent PRs (#332, #333) merged; the README still points contributors atmainnet-staging, which was last updated in 2024. Happy to retarget.